#include "main.h"
#include "TLVPacketer.h"

CMain  G_Main;

ostream &
operator << (ostream& out, const CCardSet &set)
{
	for (CCardSet::const_iterator it = set.begin(); it != set.end(); it++)
	{
		out << (*it)->Value << " ";
	}
	return out << endl;
}

CMsgManager *GetMsgManager()
{
	static CMsgManager MsgManager;
	return &MsgManager;
}

CBasicGameCard *GetBasicCard()
{
	return &G_Main.BasicCard;
}

void
CMsgSocket::BeginAccept()
{
	string sock, command, arg;
	TLVpacketer pa;

	while(1)
	{
		cout << "Command:" ;
		cin >> sock >> command;
		if ( command == "new" )
			Main->MPostMsg(MSG_SOCKET_ACCEPT, 0, sock);
		else 
		{
			pa[PACKET_TYPE_SOCKET] = sock;
			pa[PACKET_TYPE_CONTENT] = command;
			if ( command == "join" )
			{
				cin >> arg;
				pa[PACKET_TYPE_HOST] = arg;
			}
			pa.MakePacket();
			Main->MPostMsg(MSG_SOCKET_RECV, 0, pa);
		}
	}
}

void 
CMain::MOnRecvMsg(unsigned int type, T_LParameter lp, const DataFlow &data)
{
	string sock, command, arg;
	TLVpacketer pa;
	CGameInstance *game;
	CUser *user;

	switch (type)
	{
	case MSG_SOCKET_ACCEPT:
		sock = data.GetData();
		//string sock(data.GetData());
		if ( MAP_NOT_CONTAIN(Users, sock) )
		{
			user = new CUser(sock);
			Users[sock] = user;
			user->StartMsgThread();
			cout << "User " << sock << " login" << endl;
		}
		break;
	case MSG_SOCKET_RECV:
		pa = data;
		sock = pa[PACKET_TYPE_SOCKET].GetData();
		command = pa[PACKET_TYPE_CONTENT].GetData();
		if ( MAP_NOT_CONTAIN(Users, sock) )
			break;
		user = Users[sock];
		if (command == "create")
		{
			if ( MAP_NOT_CONTAIN(Instances, sock) )
			{
				game = new CGameInstance();
				Instances[sock] = game;
				game->StartMsgThread();
				user->JoinGame(game->GetMD(), 1);
			}
		}
		else if (command == "start")
		{
			if ( !MAP_NOT_CONTAIN(Instances, sock) )    // only host can start game
			{
				user->StartGame();
			}
		}
		else if (command == "join")
		{
			arg = pa[PACKET_TYPE_HOST].GetData();
			if ( !MAP_NOT_CONTAIN(Instances, arg) )
			{
				game = Instances[arg];
				user->JoinGame(game->GetMD(), 0);
			}
		}
		break;
	}
}

void main()
{
	G_Main.BasicCard.Init();
	G_Main.MsgSocket.Init(&G_Main);
	G_Main.StartMsgThread();
	G_Main.MsgSocket.BeginAccept();
}